//
//  Log.h
//  sad
//
//  Created by Christopher Kemsley on 2/5/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef sad_Log_h
#define sad_Log_h

#include <sstream>
#include "URL.hpp"
#include "Exception.hpp"






// Internal type
struct	LogSettings ;






class LogStream
{
public:
	typedef enum {
		kPreferredFormatNatural ,
		kPreferredFormatTSV
	} PreferredFormat ;
	
	
	LogStream ( LogStream const & copy ) ;
	~LogStream () ;
	
	template <typename Type>
	LogStream const&	operator<<	( Type const & value ) const
		{
		if ( mStream != 0 )
			(*mStream) << value ;
		return *this ;
		}
	
	PreferredFormat	preferredFormat () const ;
	
	
private:
	std::ostream*	mStream ;
	bool			mDeleteWhenDone ;
	unsigned &		mRetainCount ;
	PreferredFormat	mFormat ;
	static unsigned i ; // dummy variable
	
	friend class Log ;
	LogStream () ;
	LogStream ( unsigned & inRetainCount , std::ostream * inStream , bool inDeleteWhenDone , PreferredFormat inFormat ) ;
} ;







class	Log
{
public:
	static void	loadConfiguration	( URL & path ) ;
	
	static void	setShowsErrors		( bool value = true ) ;
	static void	setShowsWarnings	( bool value = true ) ;
	static void	setShowsNotices		( bool value = true ) ;
	static void	setShowsStates		( bool value = true ) ;
	
	static LogStream const	error	( char const* domain ) ;
	static LogStream const	warning	( char const* domain ) ;
	static LogStream const	notice	( char const* domain ) ;
	static LogStream const	states	( char const* domain ) ;
	static LogStream const	output	() ;
	static LogStream const	statistics	( std::string const & domain ) ;
	
	static void	flush () ;
	
	static void	logException	( Exception const& exception ) ;
	
	
	template <typename Type>
	Log&	operator <<		( Type const & value )
		{
		if ( mCurrent != 0 )
			(*mCurrent) << value ;
		return *this ;
		}
	
	
private:
	static Log&	shared () ;
	
	Log () ;
	
	std::ostream*	mCurrent ;
	
	unsigned	mLogStreamReferenceCount ;
	unsigned	mOutputStreamReferenceCount ;
	unsigned	mStatsStreamReferenceCount ;
	
	static LogSettings&	settings() ;
} ;




#endif
